package cn.buildoncloud.labor.workermanapplet.sys.modules.controller;

import cn.buildoncloud.labor.workermanapplet.common.Constant;
import cn.buildoncloud.labor.workermanapplet.common.base.Result;
import cn.buildoncloud.labor.workermanapplet.dto.AppletUserDTO;
import cn.buildoncloud.labor.workermanapplet.dto.SysUserDTO;
import cn.buildoncloud.labor.workermanapplet.sys.modules.services.AuthorityService;
import cn.buildoncloud.labor.workermanapplet.util.AppletUtil;
import cn.buildoncloud.labor.workermanapplet.util.HttpUtil;
import cn.buildoncloud.labor.workermanapplet.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import org.nutz.json.Json;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 权限部分
 * Description: cn.buildoncloud.labor.workermanapplet.sys.modules.controller
 * Created by CuiZibo on 2018/11/1 17:17
 */
@RestController
@RequestMapping("/authority")
public class AuthorityController {

    private static final Logger log = LoggerFactory.getLogger(AuthorityController.class);

    @Autowired
    private AuthorityService authorityService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Value("${webSystemIP}")
    private String webSystemIP;

    /**
     * 通过code换取openid
     * @param code
     * @return
     */
    @RequestMapping("/getOpenId")
    public Object getOpenId(@RequestParam(value = "code", required = true) String code) {
        try {
            Map<String, Object> data = authorityService.getOpenIdAndCheckExists(code);
            return data;
        } catch (Exception e) {
            log.error("authority/getOpenId: ", e);
            return Result.error(Constant.API_OPERATION_FAILED);
        }

    }

    /**
     * 通过code和加密后的用户信息，解密用户信息并保存到数据库，及时更新数据
     * @param code
     * @param encryptedData
     * @param iv
     * @return
     */
    @RequestMapping("/saveOrUpdateAppletUser")
    public Object saveOrUpdateAppletUser(@RequestParam(value = "code", required = true) String code,
                                         @RequestParam(value = "encryptedData", required = true) String encryptedData,
                                         @RequestParam(value = "iv", required = true) String iv) {
        try {

            JSONObject sessionKeyAndOpenid = AppletUtil.getSessionKeyAndOpenid(code);
            String sessionKey = sessionKeyAndOpenid.getString("session_key");
            JSONObject userInfoJSON = AppletUtil.decodeUserInfo(encryptedData, sessionKey, iv);

            if (userInfoJSON == null) {
                return Result.error("参数解析失败！");
            }
            AppletUserDTO appletUserDTO = new AppletUserDTO();

            appletUserDTO.setOpenId(userInfoJSON.getString("openId"));
            appletUserDTO.setNickName(userInfoJSON.getString("nickName"));
            appletUserDTO.setGender(userInfoJSON.getString("gender"));
            appletUserDTO.setCity(userInfoJSON.getString("city"));
            appletUserDTO.setProvince(userInfoJSON.getString("province"));
            appletUserDTO.setCountry(userInfoJSON.getString("country"));
            appletUserDTO.setAvatarUrl(userInfoJSON.getString("avatarUrl"));
            if (userInfoJSON.get("unionId") != null) {
                appletUserDTO.setUnionId(userInfoJSON.getString("unionId"));
            }
            String s1 = JSONObject.toJSONString(appletUserDTO);
            Map<String, Object> map = new HashMap<>();
            map.put("userStr", s1);
            String s = HttpUtil.post(webSystemIP + "/appletUser/saveOrUpdate", map);
            Result result = Json.fromJson(Result.class, s);
            return result;
        } catch (Exception e) {
            log.error("authority/saveOrUpdateAppletUser", e);
            return Result.error(Constant.API_OPERATION_FAILED);
        }
    }

    /**
     * 发送验证码
     * @param phoneNumber
     * @param session
     * @return
     */
    @RequestMapping("/sendVerificationCode")
    public Object sendVerificationCode(@RequestParam(value = "phoneNumber", required = true) String phoneNumber,
                                       HttpSession session) {
        try {
            Map parameterMap = new HashMap<>();
            parameterMap.put("phone", phoneNumber);

            String response = HttpUtil.post(webSystemIP + "/system/usermanager/sendBindSmsByApplet", parameterMap, 1000 * 30);
            JSONObject result = JSONObject.parseObject(response);
            if (result.containsKey("code") && (int) result.get("code") == 0) {
                redisTemplate.opsForValue().set(Constant.SESSION_NAME_USER_BIND_APPLET_PHONE + ":" + phoneNumber,
                        Constant.SESSION_NAME_USER_BIND_APPLET_CODE + ":" + result.get("data").toString(),
                        70,
                        TimeUnit.SECONDS);
                return Result.success(Constant.API_OPERATION_SUCCESS, result.get("data").toString());
            } else {
                return Result.error(Constant.API_OPERATION_FAILED);
            }
        } catch (Exception e) {
            log.error("authority/sendVerificationCode", e);
            return Result.error(Constant.API_OPERATION_FAILED);
        }
    }

    /**
     * 通过手机号和web系统用户绑定
     * @param phoneNumber
     * @param code
     * @param request
     * @return
     */
    @RequestMapping("/bind")
    public Object bind(@RequestParam(value = "phoneNumber", required = true) String phoneNumber,
                       @RequestParam(value = "code", required = true) String code,
                       HttpServletRequest request) {
        try {
            String openId = request.getHeader("openId");

            if (StringUtil.isBlank(phoneNumber)) {
                return Result.error("手机号不能为空");
            }
            if (StringUtil.isBlank(code)) {
                return Result.error("验证码不能为空");
            }

            //TODO 该手机号是在web端创建了一个空的用户，为了审核小程序登陆用。
            if(!"13289576847".equals(phoneNumber)){
                String rCode = redisTemplate.opsForValue().get(Constant.SESSION_NAME_USER_BIND_APPLET_PHONE + ":" + phoneNumber);
                if (rCode == null) {
                    return Result.error("验证码超时，请重试！");
                }
                if (!(rCode.split(":")[1]).equals(code)) {
                    return Result.error("验证码错误，请重试！");
                }
            }
            SysUserDTO sysUserDTO = authorityService.querySysUserByPhone(phoneNumber);
            if (sysUserDTO == null) {
                return Result.error("该用户在云上建瓴平台未注册，请联系企业管理员！");
            }
            int i = authorityService.bind(openId, sysUserDTO.getId());
            if (i != 1) {
                redisTemplate.delete(Constant.SESSION_NAME_USER_BIND_APPLET_PHONE + ":" + phoneNumber);
                return Result.error("绑定失败，请重试！");
            }
            return Result.success(Constant.API_OPERATION_SUCCESS, sysUserDTO);
        } catch (Exception e) {
            log.error("authority/bind", e);
            return Result.error(Constant.API_OPERATION_FAILED);
        }

    }

    /**
     * 用户解绑
     * @param userId
     * @param request
     * @return
     */
    @RequestMapping("/unBind")
    public Object unBind(@RequestParam(value = "userId", required = true) String userId,
                         HttpServletRequest request) {
        try {
            String openId = request.getHeader("openId");
            AppletUserDTO appletUserDTO = authorityService.queryAppletByOpenId(openId);
            if (appletUserDTO == null || appletUserDTO.getId() == null) {
                return Result.error("小程序用户不存在，请重新授权登陆！");
            }
            boolean b = authorityService.queryIsBind(userId, appletUserDTO.getId());
            if (!b) {
                return Result.error("小程序用户没有绑定系统用户，请联系企业管理员！");
            }
            int i = authorityService.unBind(userId, appletUserDTO.getId());
            if (i != 1) {
                return Result.error("解绑失败，请重试！");
            }
            return Result.success(Constant.API_OPERATION_SUCCESS);
        } catch (Exception e) {
            log.error("authority/unBind", e);
            return Result.error(Constant.API_OPERATION_FAILED);
        }
    }

}
